package org.ww.member.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.ww.common.utils.PageUtils;
import org.ww.common.utils.Query;
import org.ww.member.dao.MemberDao;
import org.ww.member.dto.Oauth2WeiboDto;
import org.ww.member.dto.UserLoginDto;
import org.ww.member.dto.UserRegistDto;
import org.ww.member.entity.MemberEntity;
import org.ww.member.entity.MemberLevelEntity;
import org.ww.member.exception.PhoneExistException;
import org.ww.member.exception.UserNameExistException;
import org.ww.member.service.MemberLevelService;
import org.ww.member.service.MemberService;

import java.util.HashMap;
import java.util.Map;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    private static final String WEIBO_USERS_SHOW_URL = "https://api.weibo.com/2/users/show.json";
    @Autowired
    private MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(UserRegistDto dto) throws PhoneExistException{

        MemberEntity memberEntity = new MemberEntity();

        //验证用户名手机号是否重复
        this.checkPhoneIsExist(dto.getPhone());
        this.checkUserNameIsExist(dto.getUserName());

        //设置用户默认等级
        MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultMemberLevel();
        memberEntity.setLevelId(memberLevelEntity.getId());

        memberEntity.setUsername(dto.getUserName());
        memberEntity.setNickname(dto.getUserName());
        memberEntity.setMobile(dto.getPhone());
        //密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(dto.getPassword());
        memberEntity.setPassword(encode);

        //其他默认信息
        baseMapper.insert(memberEntity);

    }

    @Override
    public void checkPhoneIsExist(String phone) throws PhoneExistException{
        LambdaQueryWrapper<MemberEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(MemberEntity::getMobile,phone);
        Integer count = baseMapper.selectCount(wrapper);
        if(count > 0){
            //已经存在该手机号
            throw new PhoneExistException();
        }
    }

    @Override
    public void checkUserNameIsExist(String userName) throws UserNameExistException {
        LambdaQueryWrapper<MemberEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(MemberEntity::getUsername,userName);
        Integer count = baseMapper.selectCount(wrapper);
        if(count > 0){
            //已经存在该用户名
            throw new UserNameExistException();
        }
    }

    @Override
    public MemberEntity login(UserLoginDto dto) {
        LambdaQueryWrapper<MemberEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(MemberEntity::getUsername,dto.getLoginacct())
                .or()
                .eq(MemberEntity::getMobile,dto.getLoginacct());
        MemberEntity entity = baseMapper.selectOne(wrapper);
        if(ObjectUtils.isEmpty(entity)){
            return null;
        }

        //判断密码是否匹配
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(dto.getPassword(), entity.getPassword());
        if(matches){
            return entity;
        }else{
            return null;
        }
    }

    @Override
    public MemberEntity login(Oauth2WeiboDto dto) {
        //1、根据uid进行查询，用户是否注册，未注册则进行注册
        LambdaQueryWrapper<MemberEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(MemberEntity::getSocialUid,dto.getUid());
        MemberEntity entity = baseMapper.selectOne(wrapper);
        if(ObjectUtils.isNotEmpty(entity)){
            //2、如果查询到了将access_token进行替换掉
            LambdaUpdateWrapper<MemberEntity> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(MemberEntity::getId,entity.getId());
            updateWrapper.set(MemberEntity::getSocialUid,dto.getUid());
            updateWrapper.set(MemberEntity::getExpiresIn,dto.getExpires_in());
            updateWrapper.set(MemberEntity::getAccessToken,dto.getAccess_token());
            baseMapper.update(null,updateWrapper);
        }else{
            //进行注册，根据令牌获取微博用户信息
            try{
                entity = new MemberEntity();
                Map<String,Object> paramMap = new HashMap<>();
                paramMap.put("access_token",dto.getAccess_token());
                paramMap.put("uid",dto.getUid());
                String response = HttpUtil.get(WEIBO_USERS_SHOW_URL, paramMap);
                JSONObject jsonObject = JSON.parseObject(response);
                entity.setNickname(jsonObject.getString("name"));
                entity.setGender("m".equals(jsonObject.getString("gender")) ? 1 : 0);

            }catch (Exception e){
                e.printStackTrace();
            }

            entity.setAccessToken(dto.getAccess_token());
            entity.setSocialUid(dto.getUid());
            entity.setExpiresIn(dto.getExpires_in());
            baseMapper.insert(entity);
        }
        return entity;
    }


}